`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    02:49:10 04/21/2013 
// Design Name: 
// Module Name:    DEPPReader 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module DEPPReader(
    input clk,
	 input reset,
    input strobeA,
    input strobeD,
    output wt,
    input [7:0] eppBus,
    output [7:0] data,
    output dataReady,
    input ack
    );
// Use a 3-taps shift register to synchronize EPP_strobe to our clock
wire EPP_strobe = strobeA | strobeD;  // only one is active at a time
reg [2:0] EPP_strobe_reg;
always @(posedge clk) EPP_strobe_reg <= {EPP_strobe_reg[1:0], EPP_strobe};

// detect the strobe edges
wire EPP_strobe_edge1 = (EPP_strobe_reg[2:1]==2'b01);
wire EPP_strobe_edge2 = (EPP_strobe_reg[2:1]==2'b10);
reg allowAckReg;

// respond right away to a transaction
assign wt = strobeD ? (allowAckReg & EPP_strobe_reg[1]) : EPP_strobe_reg[1];

// EPP writes
reg [7:0] addr_reg, data_reg;
reg dataReadyReg;
always @(posedge clk) if(EPP_strobe_edge1 & strobeA) addr_reg <= eppBus;
always @(posedge clk) begin
	if(reset) begin
		data_reg <= 8'b0;
		dataReadyReg <= 0;
		allowAckReg <= 0;
		end
	else if(EPP_strobe_edge1 & strobeD) begin
		data_reg <= eppBus;
		dataReadyReg <= 1;
		allowAckReg <= allowAckReg;
		end
	else if(strobeD & ack) begin
		data_reg <= data_reg;
		dataReadyReg <= 0;
		allowAckReg <= 1;
		end
	else if(EPP_strobe_edge2 & allowAckReg) begin
		data_reg <= data_reg;
		dataReadyReg <= 0;
		allowAckReg <= 0;
		end
	else begin
		data_reg <= data_reg;
		dataReadyReg <= dataReadyReg;
		allowAckReg <= allowAckReg;
		end
	end

assign dataReady = dataReadyReg;
assign data = data_reg;
endmodule
